// 扩展2. c++ 11之后的标准线程库
/**
 *
 */
#include <iostream>
#include <thread>
#include <windows.h>

// Windows下C++使用thread时无法识别thread和mutex相关库的解决
// https://blog.csdn.net/neverever01/article/details/107155542
// 看MinGW-w64安装threads配置选啥 win32/posix
std::thread::id main_thread_id = std::this_thread::get_id();

// void *argv = NULL 默认值好像用不了
void is_main_thread(void *argv)
{
  bool is_detach = false;
  // if (argv != NULL)
  // {
  //   std::cout << "argv is not equal to NULL" << std::endl;
  //   is_detach = *((bool *)argv);
  // }
  is_detach = *((bool *)argv);
  std::cout << " Hello Concurrent World" << std::endl;
  if (main_thread_id == std::this_thread::get_id())
  {
    std::cout << "This is the main thread !" << std::endl;
  }
  else
  {
    std::cout << "This is not the main thread !" << std::endl;
  }
  if (!is_detach)
  {
    Sleep(1000);
  }
  else
  {
    // 主进程结束不影响它
    std::cout << "the thread is detach! Sleep ..." << std::endl;
    Sleep(5000);
  }

  std::cout << "is_main_thread end." << std::endl;
}

void pause_thread(int n)
{
  std::this_thread::sleep_for(std::chrono::seconds(n));
  std::cout << "pause of " << n << " seconds ended." << std::endl;
}

int main(void)
{
  bool isDetach = false;
  std::thread t(is_main_thread, &isDetach);
  // std::thread t(is_main_thread);
  std::cout << t.hardware_concurrency() << std::endl;              // 可以并发执行多少个（不准确）
  std::cout << "native_handle " << t.native_handle() << std::endl; // 可以并发执行多少个（不准确）
  // terminate called without an active exception
  // 错误：程序没有输出结果，进程僵死。这个错误是在程序运行的时候出现的，编译阶段没有任何错误
  // 原因就是std::thread在main()结束的时候，被销毁了。
  // 解决方案：调用join或者detach
  std::cout << "join start..." << std::endl;
  t.join();
  std::cout << "join ended." << std::endl;

  isDetach = true;
  std::thread a(is_main_thread, &isDetach);
  a.detach();

  const int size = 5;
  std::thread threads[size]; //默认构造
  for (int i = 0; i < size; i++)
  {
    threads[i] = std::thread(pause_thread, i + 1); // mode_assign threads
  }
  std::cout << "Done spawning threads. Now waiting for them to join." << std::endl;

  for (auto &thread : threads)
  {
    thread.join();
    // thread.detach();
  }

  std::cout << "All threads joined !" << std::endl;

  printf("-----------------end-----------------\n");
  return 0;
}